package com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.repository;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.ParseRenderedVariable;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.SpringUtils;
import com.iwhalecloud.citybrain.flow.platform.manager.application.utils.WebUtils;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.CustomFunctionVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowParticipantInfoVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.userentity.UserInfo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowParticipantRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.FlowUserTaskCustomExpressionRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.mapper.FlowFunctionConfigDAO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;
import java.util.*;

/**
 * @author lzb
 */
@Service
public class FlowUserTaskCustomExpressionRepositoryImpl implements FlowUserTaskCustomExpressionRepository {

    private transient final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RestTemplate restTemplate;


    @Override
    public List<UserInfo> customExpressionHandle(String participantId, String applyInitiator, String assignee) {
        FlowParticipantRepository flowParticipantRepository = SpringUtils.getBean(FlowParticipantRepository.class);
        FlowFunctionConfigDAO flowFunctionConfigDAO = SpringUtils.getBean(FlowFunctionConfigDAO.class);
        List<UserInfo> result = new ArrayList<>();
        String url = flowFunctionConfigDAO.getFlowFunctionConfigInfoByFunctionId(participantId).getFunctionUrl();
        String restUrl = org.apache.commons.lang3.StringUtils.trim(url);
        ResponseEntity<List> response = restTemplate.exchange(restUrl, HttpMethod.POST, this.getFunReq(applyInitiator, assignee), List.class);
        if (response.getStatusCodeValue() == 200) {
            response.getBody().stream().forEach(item -> {
                if (item instanceof Map) {
                    Map param = (Map) item;
                    String userId = String.valueOf(param.get("userId"));
                    String name = String.valueOf(Objects.nonNull(param.get("name")) ? param.get("name") : "");
                    FlowParticipantInfoVo flowParticipantInfo = new FlowParticipantInfoVo();
                    flowParticipantInfo.setParticipantId(userId);
                    flowParticipantInfo.setParticipantType("STA");
                    flowParticipantInfo.setParticipantName(name);
                    flowParticipantInfo.setCreateTime(new Date());
                    flowParticipantInfo.setUpdateTime(new Date());
                    flowParticipantRepository.insertParticipant(flowParticipantInfo);
                    UserInfo userInfo = new UserInfo();
                    userInfo.setUserCode(userId);
                    userInfo.setUserName(name);
                    result.add(userInfo);
                }
            });
        } else {
            logger.error("自定义函数请求失败，请检查URL、传入正确的参数");
        }
        return result;
    }

    /**
     * @param funId          自定义函数id
     * @param applyInitiator 拟稿人id
     * @return List<CustomFunctionVo>
     */
//    @Override
    public List<CustomFunctionVo> getCustomFunctionByFunId(String funId, String applyInitiator, String assignee) {
        FlowFunctionConfigDAO flowFunctionConfigDAO = SpringUtils.getBean(FlowFunctionConfigDAO.class);
        List<CustomFunctionVo> result = new ArrayList<>();
        String url = flowFunctionConfigDAO.getFlowFunctionConfigInfoByFunctionId(funId).getFunctionUrl();
        String restUrl = org.apache.commons.lang3.StringUtils.trim(url);
        try {
            // 发放http请求
            ResponseEntity<Object> response = restTemplate.exchange(restUrl, HttpMethod.POST, this.getFunReq(applyInitiator, assignee), Object.class);

            // 响应成功
            if (response != null && response.getStatusCode().value() == 200) {

                // 解析响应体
                LinkedHashMap linkedHashMap = (LinkedHashMap) response.getBody();

                // 获取并组装数据集合
                if (!MapUtils.isEmpty(linkedHashMap)) {
                    List dataList = (List) linkedHashMap.get("data");
                    if (CollectionUtils.isNotEmpty(dataList)) {
                        for (Object obj : dataList) {
                            LinkedHashMap objMap = (LinkedHashMap) obj;
                            String userId = String.valueOf(objMap.get("userId"));
                            String name = String.valueOf(objMap.get("name"));
                            // 人员所属的组织ID
                            Long orgId = Long.valueOf(String.valueOf(objMap.get("orgId")));
                            // 人员所属的组织名称
                            String orgName = String.valueOf(objMap.get("orgName"));
                            CustomFunctionVo vo = new CustomFunctionVo();
                            vo.setUserId(userId);
                            vo.setName(name);
                            vo.setOrgId(orgId);
                            vo.setOrgName(orgName);
                            result.add(vo);
                        }
                    }
                }
            } else {
                logger.error("自定义函数请求失败，请检查URL、传入正确的参数");
            }
        } catch (Exception ex) {
            logger.error("getCustomFunctionByFunId fail:" + ex.getMessage());
        }
        return result;
    }

    @Override
    public List<CustomFunctionVo> getCustomFunctionByFunId(String funId, String applyInitiator, String assignee, Map<String, Object> variables) {
        FlowFunctionConfigDAO flowFunctionConfigDAO = SpringUtils.getBean(FlowFunctionConfigDAO.class);
        List<CustomFunctionVo> result = new ArrayList<>();
        String url = flowFunctionConfigDAO.getFlowFunctionConfigInfoByFunctionId(funId).getFunctionUrl();
        // 请求的地址url
        String restUrl = ParseRenderedVariable.parseRenderedVariable(StringUtils.trim(url), variables);
        Map<String, String> params = WebUtils.parseQuery(restUrl);
        restUrl = restUrl.indexOf("?") > 0 ? restUrl.substring(0, restUrl.indexOf("?")) : restUrl;
        try {
            // 发放http请求
            ResponseEntity<Object> response = restTemplate.exchange(restUrl, HttpMethod.POST, this.getFunReq(params,applyInitiator,assignee), Object.class);

            // 响应成功
            if (response != null && response.getStatusCode().value() == 200) {

                // 解析响应体
                LinkedHashMap linkedHashMap = (LinkedHashMap) response.getBody();

                // 获取并组装数据集合
                if (!MapUtils.isEmpty(linkedHashMap)) {
                    List dataList = (List) linkedHashMap.get("data");
                    if (CollectionUtils.isNotEmpty(dataList)) {
                        for (Object obj : dataList) {
                            LinkedHashMap objMap = (LinkedHashMap) obj;
                            String userId = String.valueOf(objMap.get("userId"));
                            String name = String.valueOf(objMap.get("name"));
                            // 人员所属的组织ID
                            Long orgId = Long.valueOf(String.valueOf(objMap.get("orgId")));
                            // 人员所属的组织名称
                            String orgName = String.valueOf(objMap.get("orgName"));
                            CustomFunctionVo vo = new CustomFunctionVo();
                            vo.setUserId(userId);
                            vo.setName(name);
                            vo.setOrgId(orgId);
                            vo.setOrgName(orgName);
                            result.add(vo);
                        }
                    }
                }
            } else {
                logger.error("自定义函数请求失败，请检查URL、传入正确的参数");
            }
        } catch (Exception ex) {
            logger.error("getCustomFunctionByFunId fail:" + ex.getMessage());
        }
        return result;
    }

    private HttpEntity<String> getFunReq(String applyInitiator, String assignee) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setAcceptCharset(Collections.singletonList(Charset.forName("utf-8")));
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode params = objectMapper.createObjectNode();
        params.put("applyInitiator", applyInitiator);
        if (StringUtils.isNotBlank(assignee)) {
            params.put("assignee", assignee);
        }
        return new HttpEntity<String>(params.toString(), headers);
    }


    private HttpEntity<String> getFunReq(Map<String, String> params, String applyInitiator, String assignee) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setAcceptCharset(Collections.singletonList(Charset.forName("utf-8")));
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode headerParams = objectMapper.createObjectNode();
        headerParams.put("applyInitiator", applyInitiator);
        if (StringUtils.isNotBlank(assignee)) {
            headerParams.put("assignee", assignee);
        }
        params.forEach((key, value) -> {
            headerParams.put(key, value);
        });
        return new HttpEntity<String>(headerParams.toString(), headers);
    }
}
